package com.sgb.kjwl.utils;

import android.Manifest;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageInfo;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.Build;
import android.os.Environment;
import android.provider.Settings;
import android.util.Log;
import android.view.View;
import android.widget.FrameLayout;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.TextView;

import com.apeng.permissions.EsayPermissions;
import com.apeng.permissions.OnPermission;
import com.google.gson.Gson;
import com.sgb.kjwl.AppActivity;
import com.sgb.kjwl.R;
import com.sgb.kjwl.api.UrlConfig;
import com.sgb.kjwl.model.entity.UpdateEntity;
import com.sgb.kjwl.service.UpdateService;
import com.sgb.kjwl.view.widget.NumberProgressBar;
import com.swgk.core.BaseAppHelper;
import com.swgk.core.dialog.RoundCornerDialog;
import com.swgk.core.BaseAppApplication;
import com.swgk.core.mmkvutil.CacheMarker;
import com.swgk.core.mmkvutil.MkvUtils;
import com.swgk.core.util.MToast;
import com.swgk.core.util.RomUtil;

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;

import androidx.annotation.RequiresApi;
import androidx.core.app.NotificationManagerCompat;
import androidx.core.content.FileProvider;
import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;

import static android.app.Notification.EXTRA_CHANNEL_ID;
import static android.provider.Settings.EXTRA_APP_PACKAGE;

public class UpdateUtils {

    private boolean isDownLoading;
    private static UpdateUtils updateUtils1;

    /**
     * 下载所需的存储权限
     */
    static final String[] PERMISSIONS = new String[]{
            Manifest.permission.READ_EXTERNAL_STORAGE,
            // TODO: 2021/3/5 修改增加下面权限
//            Manifest.permission.SYSTEM_ALERT_WINDOW,
            Manifest.permission.WRITE_EXTERNAL_STORAGE//读取手机内存权限
    };

    public static UpdateUtils getInstance() {
        if (updateUtils1 == null) {
            updateUtils1 = new UpdateUtils();
        }
        return updateUtils1;
    }

    public void getNewVersion(AppActivity context, boolean isCheck) {
        if (isDownLoading) {
            return;
        }
        isDownLoading = true;
        String upDataURL = UrlConfig.UPDATE_URL;
        OkHttpClient client = new OkHttpClient();
        String upData = String.format(upDataURL, getLocalVersion(context));
        Request request = new Request.Builder().url(upData).build();
        client.newCall(request).enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {
                if (response.isSuccessful()) {
                    Gson gson = new Gson();
                    UpdateEntity updateEntity = gson.fromJson(response.body().string(), UpdateEntity.class);
                    File file = new File(context.getExternalFilesDir("apk" + File.separator + "download"), "sgb_" + updateEntity.getVersion_code());
                    String fileName = "sgb_" + updateEntity.getVersion_code() + ".apk";
                    if (!updateEntity.isIs_update()) {
                        isDownLoading = false;
                        if (isCheck) {
                            context.runOnUiThread(new Runnable() {
                                @Override
                                public void run() {
                                    file.deleteOnExit();
                                    MToast.showToast(context, "当前已经是最新版本");
                                }
                            });
                        }
                    } else {
                        if (isCheck || updateEntity.isForce_update()){//设置页面用户直接点击
                            updatePermissionCheck(context, updateEntity, file, fileName);
                        }else {//校验用户是否取消更新
                            try {
                                int cancelVersionCode = MkvUtils.get().getInt(MkvUtils.CacheModular, CacheMarker.cancelUpdateVersionCode, 1);
                                if (Integer.parseInt(updateEntity.getVersion_code()) > cancelVersionCode){
                                    updatePermissionCheck(context, updateEntity, file, fileName);
                                }else {
                                    //判断上次取消更新的时间据目前是否大于24小时
                                    long cancelUpdateTime = MkvUtils.get().getLong(MkvUtils.CacheModular, CacheMarker.cancelUpdateTime, 1);
                                    if (System.currentTimeMillis()-cancelUpdateTime > 12*60*60*1000){
                                        updatePermissionCheck(context, updateEntity, file, fileName);
                                    }else {
                                        isDownLoading = false;
                                    }
                                }
                            }catch (Exception e){
                                updatePermissionCheck(context, updateEntity, file, fileName);
                            }
                        }
                    }
                }
            }
        });
    }

    private void openNotificationManager(Context context) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            Intent intent = new Intent();
            intent.setAction("android.settings.APP_NOTIFICATION_SETTINGS");
            intent.putExtra("app_package", context.getPackageName());
            intent.putExtra("app_uid", context.getApplicationInfo().uid);
            context.startActivity(intent);
        } else if (Build.VERSION.SDK_INT == Build.VERSION_CODES.KITKAT) {
            Intent intent = new Intent();
            intent.setAction(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
            intent.addCategory(Intent.CATEGORY_DEFAULT);
            intent.setData(Uri.parse("package:" + context.getPackageName()));
            context.startActivity(intent);
        }
    }

    private void updatePermissionCheck(AppActivity context, UpdateEntity updateEntity, File file, String fileName) {
        context.runOnUiThread(new Runnable() {
            @Override
            public void run() {
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                    //openBrowser(context, updateEntity.getDownload_url());
                    //6.0以上运行时权限处理
                    EsayPermissions.with(context).constantRequest().permission(PERMISSIONS).request(new OnPermission() {
                        @Override
                        public void hasPermission(List<String> granted, boolean isAll) {
                            if (isAll) {
                                showNewUpdataDialog(context, updateEntity, file, fileName);
                            } else {
                                MToast.showToast(BaseAppHelper.get().getInstance(), "获取权限失败");
                            }
                        }

                        @Override
                        public void noPermission(List<String> denied, boolean quick) {
                            try {
                                if (quick) {
                                    MToast.showToast(BaseAppHelper.get().getInstance(), "被永久拒绝授权，请手动授予权限");
                                    //如果是被永久拒绝就跳转到应用权限系统设置页面
                                    EsayPermissions.gotoPermissionSettings(BaseAppHelper.get().getInstance());
                                } else {
                                    MToast.showToast(BaseAppHelper.get().getInstance(), "获取权限失败");
                                }
                            } catch (Exception e) {
                                e.printStackTrace();
                            }
                        }
                    });
                } else {
                    showNewUpdataDialog(context, updateEntity, file, fileName);
                }
            }
        });
    }

    /**
     * 老更新方式
     * @param context
     * @param updateEntity
     * @param file
     * @param fileName
     */
    private void showUpdataDialog(AppActivity context, UpdateEntity updateEntity, File file, String fileName) {
       context.runOnUiThread(new Runnable() {
            @Override
            public void run() {
                View view = View.inflate(context, R.layout.dialog_update_two_btn, null);
                final RoundCornerDialog roundCornerDialog = new RoundCornerDialog(context, 0, 0, view, R.style.RoundCornerDialog);
                roundCornerDialog.show();
                roundCornerDialog.setCanceledOnTouchOutside(true);// 设置点击屏幕Dialog不消失
                roundCornerDialog.setCancelable(true);
                TextView tvCancel = view.findViewById(R.id.tv_logout_cancel);
                TextView tvConfirm = view.findViewById(R.id.tv_logout_confirm);
                TextView tvMessage = view.findViewById(R.id.tv_message);
                TextView tvVersion = view.findViewById(R.id.tv_version);
                View line = view.findViewById(R.id.line);

                if (updateEntity.isForce_update()) {
                    roundCornerDialog.setCanceledOnTouchOutside(true);
                    roundCornerDialog.setCancelable(false);
                    tvCancel.setVisibility(View.GONE);
                    line.setVisibility(View.GONE);
                }

                tvVersion.setText(updateEntity.getVersion_name());
                tvMessage.setText(updateEntity.getDescribe());

                tvCancel.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View view) {
                        roundCornerDialog.dismiss();
                    }
                });

                tvConfirm.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View view) {
                        if (RomUtil.isOppo() || "2".equals(updateEntity.getUpdate_method())) { //前台下载
                            UpdateUtilsForeground.getNewVersion(context, updateEntity, file, fileName);
                        } else { //后台下载
                            NotificationManagerCompat manager = NotificationManagerCompat.from(context);
                            // areNotificationsEnabled方法的有效性官方只最低支持到API 19，低于19的仍可调用此方法不过只会返回true，即默认为用户已经开启了通知。
                            boolean isOpened = manager.areNotificationsEnabled();
                            if (isOpened){
                                //开启后台下载
                                loadNewVersionProgress(context, updateEntity.getDownload_url(), file, fileName);
                            }else {//未开启通知直接前台下载
                                UpdateUtilsForeground.getNewVersion(context, updateEntity, file, fileName);
                            }
                            //checkNotifySetting(context, updateEntity.getDownload_url(), file, fileName);
                        }
                        roundCornerDialog.dismiss();
                    }
                });
                /*isDownLoading = true;
                AlertDialog.Builder builder = new AlertDialog.Builder(context);
                builder.setTitle("应用有更新版本:" + updateEntity.getVersion_name()).setMessage(updateEntity.getDescribe()).setPositiveButton("立即更新", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialogInterface, int i) {
                        if (RomUtil.isOppo() || "2".equals(updateEntity.getUpdate_method())) { //前台下载
                            UpdateUtilsForeground.getNewVersion(context, updateEntity, file, fileName);
                        } else { //后台下载
                            loadNewVersionProgress(context, updateEntity.getDownload_url(), file, fileName);
                        }
                    }
                }).setCancelable(false);
                if (!updateEntity.isForce_update()) {
                    builder.setNegativeButton("取消", new DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialogInterface, int i) {
                        }
                    });
                }

                AlertDialog alertDialog = builder.create();
                alertDialog.setCanceledOnTouchOutside(false);
                alertDialog.show();

                Window dialogWindow = alertDialog.getWindow();
                WindowManager m = context.getWindowManager();
                Display d = m.getDefaultDisplay(); // 获取屏幕宽、高
                WindowManager.LayoutParams p = dialogWindow.getAttributes(); // 获取对话框当前的参数值
                // 设置宽度
                p.width = (int) (d.getWidth() * 0.95); // 宽度设置为屏幕的0.95
                p.gravity = Gravity.CENTER;//设置位置
                //p.alpha = 0.8f;//设置透明度
                dialogWindow.setAttributes(p);*/
            }
        });
    }


    /**
     * 新更新方式
     * @param context
     * @param updateEntity
     * @param file
     * @param fileName
     */
    private void showNewUpdataDialog(AppActivity context, UpdateEntity updateEntity, File file, String fileName) {
        context.runOnUiThread(new Runnable() {
            @Override
            public void run() {
                View view = View.inflate(context, UpdateLayoutUtils.getLayout(), null);
                final RoundCornerDialog roundCornerDialog = new RoundCornerDialog(context, 0, 0, view, R.style.RoundCornerDialog);
                roundCornerDialog.show();
                roundCornerDialog.setCanceledOnTouchOutside(true);// 设置点击屏幕Dialog不消失
                roundCornerDialog.setCancelable(false);
                TextView tvVersion = view.findViewById(R.id.tv_version);//版本号
                TextView tvMessage = view.findViewById(R.id.tv_message);//更新内容
                LinearLayout llUpdateBut = view.findViewById(R.id.ll_update_but);//立即更新、稍后更新布局
                TextView tvUpdateForce = view.findViewById(R.id.tv_update_force);//立即更新按钮
                TextView tvConfirm = view.findViewById(R.id.tv_cancel);//稍后更新按钮
                LinearLayout llProgress = view.findViewById(R.id.ll_progress);//更新进度条布局
                SaundProgressBar regularprogressbar = view.findViewById(R.id.regularprogressbar);//进度条布局
                regularprogressbar.setProgressBarClickable(regularprogressbar,false);
                SaundSeekBar seekbar = view.findViewById(R.id.seekbar);//进度布局
                seekbar.setSeekBarClickable(seekbar,false);
                Drawable seekIndicator = context.getResources().getDrawable(R.drawable.progress_transparent_indicator);
                Rect seekBounds = new Rect(0, 0, 60, 40);
                seekIndicator.setBounds(seekBounds);
                seekbar.setProgressIndicator(seekIndicator);
               if (updateEntity.isForce_update()) {
                    //只展示立即更新按钮
                    tvConfirm.setVisibility(View.GONE);
                }else {
                    //立即更新按钮和稍后更新按钮都展示
                    tvConfirm.setVisibility(View.VISIBLE);
                }
                tvVersion.setText(updateEntity.getVersion_name());
                tvMessage.setText(updateEntity.getDescribe());

                //稍后更新按钮
                tvConfirm.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View view) {
                        isDownLoading = false;
                        MkvUtils.get().putInt(MkvUtils.CacheModular, CacheMarker.cancelUpdateVersionCode, Integer.parseInt(updateEntity.getVersion_code()));
                        MkvUtils.get().putLong(MkvUtils.CacheModular, CacheMarker.cancelUpdateTime, System.currentTimeMillis());
                        roundCornerDialog.dismiss();
                    }
                });
                //立即更新
                tvUpdateForce.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View view) {
                       // toUpdate(context, updateEntity,fileName,file,npbBar,roundCornerDialog);
                        toUpdate(context, updateEntity,fileName,file,regularprogressbar,seekbar,roundCornerDialog);
                        llUpdateBut.setVisibility(View.GONE);
                        llProgress.setVisibility(View.VISIBLE);
                    }
                });
            }
        });
    }
 private void toUpdate(AppActivity context, UpdateEntity updateEntity, String fileName, File file, SaundProgressBar regularprogressbar,SaundSeekBar seekbar,  RoundCornerDialog roundCornerDialog){
        if (RomUtil.isOppo() || "2".equals(updateEntity.getUpdate_method())) { //前台下载
            loadNewVersionProgressForeground(context, updateEntity.getDownload_url(), fileName, regularprogressbar,seekbar, roundCornerDialog);
        } else { //后台下载
            NotificationManagerCompat manager = NotificationManagerCompat.from(context);
            boolean isOpened = manager.areNotificationsEnabled();
            if (isOpened){
                //开启后台下载
                loadNewVersionProgress(context, updateEntity.getDownload_url(), file, fileName);
                roundCornerDialog.dismiss();
            }else {//未开启通知直接前台下载
                loadNewVersionProgressForeground(context, updateEntity.getDownload_url(), fileName, regularprogressbar,seekbar, roundCornerDialog);
            }
        }
    }
   /* private void toUpdate(AppActivity context, UpdateEntity updateEntity, String fileName, File file, NumberProgressBar npbBar, RoundCornerDialog roundCornerDialog){
        if (RomUtil.isOppo() || "2".equals(updateEntity.getUpdate_method())) { //前台下载
            loadNewVersionProgressForeground(context, updateEntity.getDownload_url(), fileName, npbBar, roundCornerDialog);
        } else { //后台下载
            NotificationManagerCompat manager = NotificationManagerCompat.from(context);
            boolean isOpened = manager.areNotificationsEnabled();
            if (isOpened){
                //开启后台下载
                loadNewVersionProgress(context, updateEntity.getDownload_url(), file, fileName);
                roundCornerDialog.dismiss();
            }else {//未开启通知直接前台下载
                loadNewVersionProgressForeground(context, updateEntity.getDownload_url(), fileName, npbBar, roundCornerDialog);
            }
        }
    }*/

    private void loadNewVersionProgressForeground(Activity context, final String uri, String fileName, SaundProgressBar regularprogressbar,SaundSeekBar seekbar, RoundCornerDialog roundCornerDialog) {
        new Thread() {
            @Override
            public void run() {
                try {
                    //判断是否有已下载完成的包
                    long fileSize = MkvUtils.get().getLong(MkvUtils.CommomData,fileName);
                    if (fileSize > 0){
                        File file = new File(Environment.getExternalStorageDirectory(), fileName);
                        long length = file.length();
                        if (fileSize == length){
                            install(context, file);
                            roundCornerDialog.dismiss();
                        }else {
                            File files = getFileFromServer(uri, fileName, regularprogressbar,seekbar);
                            sleep(2000);
                            install(context, files);
                            roundCornerDialog.dismiss();
                        }
                    }else {
                        File file = getFileFromServer(uri, fileName, regularprogressbar,seekbar);
                        sleep(2000);
                        install(context, file);
                        roundCornerDialog.dismiss();
                    }

                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }.start();
    }

    private static File getFileFromServer(String uri, String fileName,SaundProgressBar regularprogressbar,SaundSeekBar seekbar) throws Exception {
        //如果相等的话表示当前的sdcard挂载在手机上并且是可用的
        if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
            URL url = new URL(uri);
            HttpURLConnection conn = (HttpURLConnection) url.openConnection();
            conn.setConnectTimeout(5000);
            float contentLength = conn.getContentLength()/(1024*1024);
            InputStream is = conn.getInputStream();

            if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.N) {
                long contentLengthLong = conn.getContentLengthLong();

                MkvUtils.get().putLong(MkvUtils.CommomData,fileName,contentLengthLong);
            }

            File file = new File(Environment.getExternalStorageDirectory(), fileName);
            FileOutputStream fos = new FileOutputStream(file);
            BufferedInputStream bis = new BufferedInputStream(is);
            byte[] buffer = new byte[1024];
            int len;
            int total = 0;
            while ((len = bis.read(buffer)) != -1) {
                fos.write(buffer, 0, len);
                total += len;
                float currentSize = total/(1024*1024);
                int rate = Math.round((currentSize / contentLength)*100);
                if (rate > regularprogressbar.getProgress()){
                    regularprogressbar.setProgress(rate);
                    seekbar.setProgress(rate);
                }
            }
            fos.close();
            bis.close();
            is.close();
            return file;
        } else {
            return null;
        }
    }

    //检查通知权限是否开启
    private void checkNotifySetting(AppActivity context, String url, File file, String fileName) {
        NotificationManagerCompat manager = NotificationManagerCompat.from(context);
        // areNotificationsEnabled方法的有效性官方只最低支持到API 19，低于19的仍可调用此方法不过只会返回true，即默认为用户已经开启了通知。
        boolean isOpened = manager.areNotificationsEnabled();
        if (isOpened) {
            //开启后台下载
            loadNewVersionProgress(context, url, file, fileName);
        } else {
            //跳转设置页面
            try {
                // 根据isOpened结果，判断是否需要提醒用户跳转AppInfo页面，去打开App通知权限
                Intent intent = new Intent();
                intent.setAction(Settings.ACTION_APP_NOTIFICATION_SETTINGS);
                //这种方案适用于 API 26, 即8.0（含8.0）以上可以用
                intent.putExtra(EXTRA_APP_PACKAGE, context.getPackageName());
                intent.putExtra(EXTRA_CHANNEL_ID, context.getApplicationInfo().uid);

                //这种方案适用于 API21——25，即 5.0——7.1 之间的版本可以使用
                intent.putExtra("app_package", context.getPackageName());
                intent.putExtra("app_uid", context.getApplicationInfo().uid);

                context.startActivity(intent);
            } catch (Exception e) {
                e.printStackTrace();
                // 出现异常则跳转到应用设置界面：锤子坚果3——OC105 API25
                Intent intent = new Intent();

                //下面这种方案是直接跳转到当前应用的设置界面。
                intent.setAction(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
                Uri uri = Uri.fromParts("package", context.getPackageName(), null);
                intent.setData(uri);
                context.startActivity(intent);
            }
        }
    }

    private void loadNewVersionProgress(AppActivity context, final String uri, File file, String fileName) {
        //判断应用是否开启了通知权限 4.4以上可用，4.4以下默认返回true
        NotificationManagerCompat manager = NotificationManagerCompat.from(context);
        boolean isOpened = manager.areNotificationsEnabled();
        if (isOpened) {
            loadNewData(context, uri, file, fileName);
        } else {
            isDownLoading = false;
            openNotificationManager(context);
        }
    }

    private void loadNewData(Activity context, final String uri, File file, String fileName) {
        File filePash = new File(file, fileName);
        if (filePash.exists()) {
            install(context, filePash);
            return;
        }
        context.runOnUiThread(new Runnable() {
            @Override
            public void run() {
                MToast.showToast(context,"版本更新下载中");
            }
        });
        isDownLoading = true;
        Intent intent = new Intent(context, UpdateService.class);
        intent.putExtra("url", uri);
        intent.putExtra("filePath", file.getAbsolutePath());
        intent.putExtra("fileName", fileName);
        context.startService(intent);
    }

    public void install(Activity context, File apkFile) {
        isDownLoading = false;
        Intent intent = new Intent(Intent.ACTION_VIEW);
        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
            Log.w("test", "版本大于 N ，使用 fileProvider 进行安装");
            intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
            Uri contentUri = FileProvider.getUriForFile(context, context.getPackageName() + ".fileProvider", apkFile);
            intent.setDataAndType(contentUri, "application/vnd.android.package-archive");
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                boolean hasInstallPermission = context.getPackageManager().canRequestPackageInstalls();
                if (!hasInstallPermission) {
                    startInstallPermissionSettingActivity(context);
                }
            }
        } else {
            Log.w("test", "正常进行安装");
            intent.setDataAndType(Uri.fromFile(apkFile), "application/vnd.android.package-archive");
        }
        try {
            context.startActivity(intent);
            //如果不加，最后不会提示完成、打开。
            new Thread(){
                @Override
                public void run() {
                    super.run();
                    try {
                        Thread.sleep(3000);//休眠3秒
                        android.os.Process.killProcess(android.os.Process.myPid());
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }.start();
        } catch (Exception e) {
            Log.d("test", e.toString());
        }
    }

    @RequiresApi(api = Build.VERSION_CODES.O)
    private void startInstallPermissionSettingActivity(Context context) {
        //没有权限让调到设置页面进行开启权限；
        Uri packageURI = Uri.parse("package:" + context.getPackageName());
        Intent intent = new Intent(Settings.ACTION_MANAGE_UNKNOWN_APP_SOURCES, packageURI);
        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        context.startActivity(intent);
    }

    /* 获取本地软件版本号
     */
    public int getLocalVersion(Context context) {
        int localVersion = 1;
        try {
            PackageInfo packageInfo = context.getApplicationContext()
                    .getPackageManager()
                    .getPackageInfo(context.getPackageName(), 0);
            localVersion = packageInfo.versionCode;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return localVersion;
    }
}
